Import libraries
Link to Pandas Documentation: https://pandas.pydata.org/docs/index.html
Link to datareader Documentation: https://pandas-datareader.readthedocs.io/en/latest/index.html
Link to Yf Documentation: https://pandas-datareader.readthedocs.io/en/latest/readers/yahoo.html
Link to Plotly Documentation: https://plotly.com/python/
# !pip install pandas
# !pip install pandas-datareader
# !pip install yfinance
# !pip install datetime
# !pip install plotly_express
import pandas as pd
from pandas_datareader import data as pdr
import numpy as np
import yfinance as yf
import datetime as dt
import plotly.express as px
import plotly.graph_objects as go
# Define the start and end dates, last 5 years
end = dt.datetime.now()
start = end - dt.timedelta(days = 365*5)
# define Tickers
tk = input('Enter the ticker code: ')
tickers = [tk]
file_name = tk + ".csv"
yf.pdr_override()
Enter the ticker code: SPY
#obtain data and save as CSV
df = pdr.get_data_yahoo(tickers, start = start, end = end)
df.to_csv(file_name)
df.head(2)
[*********************100%%**********************] 1 of 1 completed
| Open | High | Low | Close | Adj Close | Volume | |
|---|---|---|---|---|---|---|
| Date | ||||||
| 2018-11-12 | 277.190002 | 277.459991 | 271.98999 | 272.570007 | 250.745529 | 99673600 |
| 2018-11-13 | 273.089996 | 275.329987 | 271.25000 | 272.059998 | 250.276337 | 98176600 |
#read CSV file
stock_df = pd.read_csv(file_name)
# Test for null values, and show info
stock_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1258 entries, 0 to 1257 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Date 1258 non-null object 1 Open 1258 non-null float64 2 High 1258 non-null float64 3 Low 1258 non-null float64 4 Close 1258 non-null float64 5 Adj Close 1258 non-null float64 6 Volume 1258 non-null int64 dtypes: float64(5), int64(1), object(1) memory usage: 68.9+ KB
#insert 'Daily Return' column
stock_df['Daily Return'] = stock_df['Adj Close'].pct_change(1) * 100
# replace the first row, changes null for 0
stock_df['Daily Return'].replace(np.nan, 0, inplace = True)
stock_df
| Date | Open | High | Low | Close | Adj Close | Volume | Daily Return | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2018-11-12 | 277.190002 | 277.459991 | 271.989990 | 272.570007 | 250.745529 | 99673600 | 0.000000 |
| 1 | 2018-11-13 | 273.089996 | 275.329987 | 271.250000 | 272.059998 | 250.276337 | 98176600 | -0.187119 |
| 2 | 2018-11-14 | 274.160004 | 274.609985 | 268.450012 | 270.200012 | 248.565231 | 125335900 | -0.683686 |
| 3 | 2018-11-15 | 268.779999 | 273.540009 | 267.010010 | 273.019989 | 251.159409 | 135101400 | 1.043661 |
| 4 | 2018-11-16 | 271.790009 | 274.750000 | 271.209991 | 273.730011 | 251.812607 | 126668000 | 0.260073 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1253 | 2023-11-06 | 435.470001 | 436.149994 | 433.679993 | 435.690002 | 435.690002 | 67831700 | 0.230049 |
| 1254 | 2023-11-07 | 435.690002 | 437.589996 | 434.510010 | 436.929993 | 436.929993 | 64256100 | 0.284604 |
| 1255 | 2023-11-08 | 437.549988 | 438.089996 | 434.869995 | 437.250000 | 437.250000 | 61746000 | 0.073240 |
| 1256 | 2023-11-09 | 438.429993 | 438.470001 | 433.399994 | 433.839996 | 433.839996 | 83174400 | -0.779875 |
| 1257 | 2023-11-10 | 435.980011 | 440.929993 | 433.829987 | 440.609985 | 440.609985 | 89462200 | 1.560481 |
1258 rows × 8 columns
stock_df.describe().round(2)
| Open | High | Low | Close | Adj Close | Volume | Daily Return | |
|---|---|---|---|---|---|---|---|
| count | 1258.00 | 1258.00 | 1258.00 | 1258.00 | 1258.00 | 1.258000e+03 | 1258.00 |
| mean | 369.52 | 371.87 | 367.00 | 369.59 | 356.92 | 8.579414e+07 | 0.05 |
| std | 63.99 | 64.10 | 63.84 | 63.99 | 68.18 | 4.241795e+07 | 1.34 |
| min | 228.19 | 229.68 | 218.26 | 222.95 | 211.44 | 2.027000e+07 | -10.94 |
| 25% | 306.26 | 308.49 | 302.95 | 307.03 | 289.18 | 5.922118e+07 | -0.53 |
| 50% | 384.43 | 387.63 | 380.91 | 384.32 | 375.25 | 7.639710e+07 | 0.07 |
| 75% | 424.54 | 427.18 | 421.15 | 424.89 | 416.17 | 9.793685e+07 | 0.73 |
| max | 479.22 | 479.98 | 476.06 | 477.71 | 464.92 | 3.922207e+08 | 9.06 |
Used Plotly Express for data visualization
# Define a function that performs interactive data visualization using Plotly Express
def plotly_data(df, title):
# Create figure
fig = go.Figure()
# Set title
fig.update_layout(title_text = title)
# For loop that plots all stock prices in the pandas dataframe df
# starts with 1, to skip the date column
for i in df.columns[1:]:
# Add range slider
fig.update_layout(xaxis=dict(rangeselector = dict(buttons=list([dict(count=1, label="1m", step="month", stepmode="backward"), dict(count=6, label="6m", step="month", stepmode="backward"), dict(count=1, label="YTD", step="year", stepmode="todate"), dict(count=1, label="1y", step="year", stepmode="backward"), dict(step="all")])), rangeslider=dict( visible=True), type="date"))
# Add line graph
fig.add_scatter(x = df['Date'], y = df[i], name = i)
# Update Layout
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
# Ploting AdjClose
plotly_data(stock_df.iloc[:, [0 , 5]], (tk + ' - Ajusted Closing Price[$]'))
# Ploting Trade Volume
plotly_data(stock_df.iloc[:, [0 , 6]], (tk +' - Trading Volume'))
# Ploting Percentage Daily Return
plotly_data(stock_df.iloc[:, [0 , 7]], (tk +' - Percentage Daily Return [%]'))